/**
 * @author        Nicolas Bottarini <nicolasbottarini@gmail.com>, 404 <http://www.proyecto404.com>
 * @version       $Rev: 3 $
 * @lastrevision  $Date: 2011-09-12 16:45:37 +0000 (Mon, 12 Sep 2011) $	 
 */
package com.proyecto404.core.collections {
	import com.proyecto404.core.BaseObject;
	import com.proyecto404.core.Check;
	import com.proyecto404.core.collections.ArrayIterator;
	import com.proyecto404.core.exception.InvalidOperationException;
	import com.proyecto404.core.exception.NotImplementedException;


	public class ReadOnlyList extends BaseObject implements IList {
		
		private var _list:IList;
		
		public function ReadOnlyList(list:IList) {
			_list = list;
		}
		
		public function withValue(value:*):IList {
			throw new InvalidOperationException("Cannot change readonly list");
		}
		
		public function withValuesFrom(values:*):IList {
			throw new InvalidOperationException("Cannot change readonly list");
		}
		
		public function insertAt(index:int, value:*):void {
			throw new InvalidOperationException("Cannot change readonly list");
		}
		
		public function set(index:int, value:*):void {
			throw new InvalidOperationException("Cannot change readonly list");
		}
		
		public function get(index:int):* {
			return _list.get(index);
		}
		
		public function removeAt(index:int):void {
			throw new InvalidOperationException("Cannot change readonly list");
		}
		
		public function find(value:*):ISet {
			return _list.find(value);
		}
		
		public function getReverseIterator():IIterator {
			return _list.getReverseIterator();
		}
		
		public function getLast():* {
			return _list.getLast();
		}
		
		public function getFirst():* {
			return _list.getFirst();
		}
		
		public function count():int {
			return _list.count();
		}
		
		public function isEmpty():Boolean {
			return _list.isEmpty();
		}
		
		public function contains(value:*):Boolean {
			return _list.contains(value);;
		}
		
		public function clear():void {
			throw new InvalidOperationException("Cannot change readonly list");
		}
		
		public function toList():IList {
			return this;
		}
		
		public function toArray():Array {
			return _list.toArray();
		}
		
		public function toSet():ISet {
			return _list.toSet();
		}
		
		public function add(value:*):void {
			throw new InvalidOperationException("Cannot change readonly list");
		}
		
		public function remove(value:*):void {
			throw new InvalidOperationException("Cannot change readonly list");
		}
		
		public function removeFromArray(array:Array):void {
			throw new InvalidOperationException("Cannot change readonly list");
		}
		
		public function removeFromCollection(collection:ICollection):void {
			throw new InvalidOperationException("Cannot change readonly list");
		}

		public function addFromArray(array:Array):void {
			throw new InvalidOperationException("Cannot change readonly list");
		}
		
		public function addFromCollection(collection:ICollection):void {
			throw new InvalidOperationException("Cannot change readonly list");
		}
		
		public function asReadOnly():ICollection {
			return this;
		}
		
		public function getIterator():IIterator {
			return _list.getIterator();
		}
		
		public function implode(separator:String = ","):String {
			return _list.implode(separator);
		}
		
		public override function toString():String {
			return "ReadOnlyList{" + implode() + "}";
		}
		
		public override function equals(value:*):Boolean {
			if(!(value is ReadOnlyList)) return false;
			return _list.equals(ReadOnlyList(value)._list);
		}

		public function collect(criteria:Function):ICollection {
			return _list.collect(criteria);;
		}
		
		public function forEach(callback:Function):void {
			return _list.forEach(callback);
		}
		
		public function map(convert:Function):ICollection {
			return _list.map(convert);
		}
		
		public function all(criteria:Function):Boolean {
			return _list.all(criteria);
		}
		
		public function any(criteria:Function):Boolean {
			return _list.any(criteria);
		}
	}
}